"""
Zebra打印机ZPL代码生成器
用于根据模板生成ZPL标签代码
"""

import os
import json
import re
from typing import Optional, Dict, Any, List, Union
from pathlib import Path
from .zpl_label_config import ZplLabelConfigManager, ZplLabelError
from ...utils.logger import get_logger

# 创建日志记录器
logger = get_logger("driver.device")


class ZPrinterGenerator:
    """
    Zebra打印机ZPL代码生成器核心类
    """

    def __init__(self, printer_labels_config: Optional[Union[str, Dict]] = None):
        """
        初始化ZPrinterGenerator

        Args:
            printer_labels_config: 配置信息，可以是JSON字符串、字典或None

        Raises:
            TypeError: 当参数类型不正确时抛出
            ValueError: 当JSON解析失败时抛出
            ZplLabelError: 当标签配置加载失败时抛出
        """
        logger.debug("初始化ZPrinterGenerator")

        # 解析printer_labels_config参数，支持str(JSON字符串)、dict、或None
        self.labels = {}
        if printer_labels_config is None:
            self.labels = {}
            logger.info("未提供标签配置，使用空配置")
        elif isinstance(printer_labels_config, dict):
            self.labels = printer_labels_config
            logger.info(f"使用字典配置，包含{len(self.labels)}个标签配置")
        elif isinstance(printer_labels_config, str):
            try:
                self.labels = json.loads(printer_labels_config)
                logger.info(f"成功解析JSON字符串配置，包含{len(self.labels)}个标签配置")
            except json.JSONDecodeError as e:
                logger.error(f"JSON解析失败: {str(e)}")
                raise ValueError(f"JSON解析失败: {str(e)}")
            except Exception as e:
                logger.error(f"解析配置字符串时发生错误: {str(e)}")
                raise ValueError(f"解析配置字符串时发生错误: {str(e)}")
        else:
            error_msg = "printer_labels_config参数必须是字符串、字典或None类型"
            logger.error(error_msg)
            raise TypeError(error_msg)

        try:
            self.label_config_manager = ZplLabelConfigManager(self.labels)
            logger.info("成功初始化标签配置管理器")
        except Exception as e:
            logger.error(f"初始化标签配置管理器失败: {str(e)}")
            raise ZplLabelError(f"初始化标签配置管理器失败: {str(e)}")

    def generate_text_by_id(self, label_id: str = None, custom_data: Optional[List[str]] = None) -> str:
        """
        生成文本标签，从配置模板中生成文本标签

        Args:
            label_id: 标签ID，从配置文件中获取对应的模板文件，默认调用text_label_default
            custom_data: 自定义数据，可选，使用配置文件默认数据，如果提供则替换模板中的内容按顺序替换

        Returns:
            str: 生成的文本标签

        Raises:
            TypeError: 当参数类型不正确时抛出
            ValueError: 当参数值不合法时抛出
            ZplLabelError: 当标签生成过程中出现错误时抛出
        """
        logger.debug(f"开始生成文本标签，label_id: {label_id}, custom_data: {custom_data}")

        if label_id is not None and not isinstance(label_id, str):
            error_msg = "label_id参数必须是字符串类型或None"
            logger.error(error_msg)
            raise TypeError(error_msg)

        if custom_data is not None and not isinstance(custom_data, list):
            error_msg = "custom_data参数必须是列表类型或None"
            logger.error(error_msg)
            raise TypeError(error_msg)

        if label_id is None:
            label_id = "text_label_default"
            logger.debug("未指定label_id，使用默认值text_label_default")

        if not label_id:
            error_msg = "label_id不能为空"
            logger.error(error_msg)
            raise ValueError(error_msg)

        try:
            result = self.label_config_manager.get_template(label_id, custom_data)
            if result is None:
                error_msg = f"未找到标签模板: {label_id}"
                logger.error(error_msg)
                raise ZplLabelError(error_msg)

            logger.info(f"成功生成文本标签，label_id: {label_id}")
            return result
        except ZplLabelError:
            # 如果是已知的ZplLabelError，直接重新抛出
            raise
        except Exception as e:
            error_msg = f"生成文本标签失败: {str(e)}"
            logger.error(error_msg)
            raise ZplLabelError(error_msg)

    def generate_barcode_by_id(self, label_id: str = None, custom_data: Optional[List[str]] = None) -> str:
        """
        生成条码标签，从配置模板中生成条码标签

        Args:
            label_id: 标签ID，从配置文件中获取对应的模板文件，默认调用barcode_label_default
            custom_data: 自定义数据，可选，使用配置文件默认数据，如果提供则替换模板中的内容按顺序替换

        Returns:
            str: 生成的条码标签

        Raises:
            TypeError: 当参数类型不正确时抛出
            ValueError: 当参数值不合法时抛出
            ZplLabelError: 当标签生成过程中出现错误时抛出
        """
        logger.debug(f"开始生成条码标签，label_id: {label_id}, custom_data: {custom_data}")

        if label_id is not None and not isinstance(label_id, str):
            error_msg = "label_id参数必须是字符串类型或None"
            logger.error(error_msg)
            raise TypeError(error_msg)

        if custom_data is not None and not isinstance(custom_data, list):
            error_msg = "custom_data参数必须是列表类型或None"
            logger.error(error_msg)
            raise TypeError(error_msg)

        if label_id is None:
            label_id = "barcode_label_default"
            logger.debug("未指定label_id，使用默认值barcode_label_default")

        if not label_id:
            error_msg = "label_id不能为空"
            logger.error(error_msg)
            raise ValueError(error_msg)

        try:
            result = self.label_config_manager.get_template(label_id, custom_data)
            if result is None:
                error_msg = f"未找到标签模板: {label_id}"
                logger.error(error_msg)
                raise ZplLabelError(error_msg)

            logger.info(f"成功生成条码标签，label_id: {label_id}")
            return result
        except ZplLabelError:
            # 如果是已知的ZplLabelError，直接重新抛出
            raise
        except Exception as e:
            error_msg = f"生成条码标签失败: {str(e)}"
            logger.error(error_msg)
            raise ZplLabelError(error_msg)

    def generate_qrcode_by_id(self, label_id: str = None, custom_data: Optional[List[str]] = None) -> str:
        """
        生成二维码标签，从配置模板中生成二维码标签

        Args:
            label_id: 标签ID，从配置文件中获取对应的模板文件，默认调用qrcode_label_default
            custom_data: 自定义数据，可选，使用配置文件默认数据，如果提供则替换模板中的内容按顺序替换

        Returns:
            str: 生成的二维码标签

        Raises:
            TypeError: 当参数类型不正确时抛出
            ValueError: 当参数值不合法时抛出
            ZplLabelError: 当标签生成过程中出现错误时抛出
        """
        logger.debug(f"开始生成二维码标签，label_id: {label_id}, custom_data: {custom_data}")

        if label_id is not None and not isinstance(label_id, str):
            error_msg = "label_id参数必须是字符串类型或None"
            logger.error(error_msg)
            raise TypeError(error_msg)

        if custom_data is not None and not isinstance(custom_data, list):
            error_msg = "custom_data参数必须是列表类型或None"
            logger.error(error_msg)
            raise TypeError(error_msg)

        if label_id is None:
            label_id = "qrcode_label_default"
            logger.debug("未指定label_id，使用默认值qrcode_label_default")

        if not label_id:
            error_msg = "label_id不能为空"
            logger.error(error_msg)
            raise ValueError(error_msg)

        try:
            result = self.label_config_manager.get_template(label_id, custom_data)
            if result is None:
                error_msg = f"未找到标签模板: {label_id}"
                logger.error(error_msg)
                raise ZplLabelError(error_msg)

            logger.info(f"成功生成二维码标签，label_id: {label_id}")
            return result
        except ZplLabelError:
            # 如果是已知的ZplLabelError，直接重新抛出
            raise
        except Exception as e:
            error_msg = f"生成二维码标签失败: {str(e)}"
            logger.error(error_msg)
            raise ZplLabelError(error_msg)

    def generate_graphics_by_id(self, label_id: str = None, custom_data: Optional[List[str]] = None) -> str:
        """
        生成图形标签，从配置模板中生成图形标签

        Args:
            label_id: 标签ID，从配置文件中获取对应的模板文件，默认调用graphics_label_default
            custom_data: 自定义数据，可选，使用配置文件默认数据，如果提供则替换模板中的内容按顺序替换

        Returns:
            str: 生成的图形标签

        Raises:
            NotImplementedError: 方法尚未实现
        """
        logger.warning(f"尝试调用未实现的方法generate_graphics_by_id，label_id: {label_id}")
        raise NotImplementedError("generate_graphics_by_id not implemented")

    def generate_image_by_id(self, label_id: str = None, custom_data: Optional[List[str]] = None) -> str:
        """
        生成图片标签，从配置模板中生成图片标签

        Args:
            label_id: 标签ID，从配置文件中获取对应的模板文件，默认调用image_label_default
            custom_data: 自定义数据，可选，使用配置文件默认数据，如果提供则替换模板中的内容按顺序替换

        Returns:
            str: 生成的图片标签

        Raises:
            NotImplementedError: 方法尚未实现
        """
        logger.warning(f"尝试调用未实现的方法generate_image_by_id，label_id: {label_id}")
        raise NotImplementedError("generate_image_by_id not implemented")